/* GPS定位传感器获取定位信息，解析串口报文获得数据 */
#include <rtthread.h>
#include <rtdevice.h>
#include <string.h>
#include <stdio.h>
#include "gps.h"

#define gps_uart "uart0"

// 全局变量定义
int lat_int = 0;
int lat_dec = 0;
int lon_int = 0;
int lon_dec = 0;
char lat_string[32] = {0};
char lon_string[32] = {0};

// 修改回调函数原型以匹配RT-Thread API要求
static rt_err_t uart0_receive_callback(rt_device_t dev, rt_size_t size)
{
    static char buffer[128] = {0};
    static int idx = 0;
    uint8_t ch;

    // 从串口读取所有可用数据
    while (rt_device_read(dev, 0, &ch, 1) == 1) {
        buffer[idx++] = ch;

        // 检测行结束符
        if (ch == '\n' || idx >= sizeof(buffer) - 1) {
            buffer[idx] = '\0'; // 添加字符串结束符
            idx = 0;

            // 解析$GPRMC语句
            if (strstr(buffer, "$GPRMC") != NULL) {
                char *fields[13];  // GPRMC有13个字段
                int i = 0;
                char *p = strtok(buffer, ",");

                // 分割字段
                while (p != NULL && i < 13) {
                    fields[i++] = p;
                    p = strtok(NULL, ",");
                }

                // 状态有效（A）时解析
                if (i >= 13 && fields[2][0] == 'A') {
                    // 解析纬度（DDMM.MMMMM）
                    char *lat_str = fields[3];
                    char deg_str[3] = {0};
                    strncpy(deg_str, lat_str, 2);  // 度（2位）
                    lat_int = atoi(deg_str);

                    char min_str[7] = {0};
                    strncpy(min_str, lat_str + 2, 6);  // 分及小数（MM.MMMMM，6位）
                    lat_dec = (int)(atof(min_str) * 10000);  // 转换为10000进制
                    sprintf(lat_string, "%s", lat_str);  // 存储纬度字符串

                    // 解析经度（DDDMM.MMMMM）
                    char *lon_str = fields[5];
                    char lon_deg_str[4] = {0};
                    strncpy(lon_deg_str, lon_str, 3);  // 度（3位）
                    lon_int = atoi(lon_deg_str);

                    char lon_min_str[7] = {0};
                    strncpy(lon_min_str, lon_str + 3, 6);  // 分及小数（MM.MMMMM，6位）
                    lon_dec = (int)(atof(lon_min_str) * 10000);  // 转换为10000进制
                    sprintf(lon_string, "%s", lon_str);  // 存储经度字符串
                }
            }
        }
    }

    return RT_EOK;
}

int gps_init(void)
{
    rt_device_t uart_dev;
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

    uart_dev = rt_device_find(gps_uart);
    if (uart_dev == RT_NULL) {
        rt_kprintf("Error: GPS UART device not found!\n");
        return -RT_ERROR;
    }

    // 配置串口参数
    config.baud_rate = BAUD_RATE_9600;    // 设置波特率为9600
    config.data_bits = DATA_BITS_8;       // 数据位8位
    config.stop_bits = STOP_BITS_1;       // 停止位1位
    config.parity    = PARITY_NONE;       // 无校验位
    config.bit_order = BIT_ORDER_LSB;     // 低位在前
    config.invert    = NRZ_NORMAL;        // 非反转
    config.bufsz     = 64;                // 缓冲区大小

    // 打开设备并设置参数
    if (rt_device_open(uart_dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK) {
        rt_kprintf("Error: Failed to open GPS UART device!\n");
        return -RT_ERROR;
    }

    if (rt_device_control(uart_dev, RT_DEVICE_CTRL_CONFIG, &config) != RT_EOK) {
        rt_kprintf("Error: Failed to configure GPS UART device!\n");
        rt_device_close(uart_dev);
        return -RT_ERROR;
    }

    // 设置接收回调函数
    rt_device_set_rx_indicate(uart_dev, uart0_receive_callback);

    rt_kprintf("GPS module initialized successfully!\n");
    return RT_EOK;
}
INIT_APP_EXPORT(gps_init);
